package com.android.demo_20220829.manager;

import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.os.Handler;

import com.android.baselibrary.tool.CommToast;
import com.android.baselibrary.tool.Log;
import com.android.demo_20220829.adapter.LogAdapter;
import com.android.demo_20220829.event.Event_SendBigBagSuccess;
import com.android.demo_20220829.ui.activity.DeviceDetailActivity;
import com.blankj.utilcode.util.ConvertUtils;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;

import cn.wandersnail.ble.Connection;
import cn.wandersnail.ble.ConnectionState;
import cn.wandersnail.ble.RequestBuilderFactory;
import cn.wandersnail.ble.WriteCharacteristicBuilder;
import cn.wandersnail.ble.WriteOptions;
import cn.wandersnail.commons.util.FileUtils;
import cn.wandersnail.commons.util.StringUtils;

public class SendFileManager {

    File file;   //
    Context mContext;
    int begin = 134250496;  //数据起始位
    Connection connection;
    UUID serviceUUID;
    UUID writeUUID;
    Handler handler = new Handler();
    LogAdapter logAdapter;

    public ConcurrentLinkedQueue<byte[]> queue_big = new ConcurrentLinkedQueue<>();  //大包数据队列
    public ConcurrentLinkedQueue<byte[]> queue_small = new ConcurrentLinkedQueue<>();  //单个包拆分20个小包队列

    public SendFileManager(Context mContext) {
        this.mContext = mContext;
    }

    public void setConnection(Connection connection, UUID serviceUUID, UUID writeUUID) {
        this.connection = connection;
        this.serviceUUID = serviceUUID;
        this.writeUUID = writeUUID;
    }

    public void setLogAdapter(LogAdapter logAdapter) {
        this.logAdapter = logAdapter;
    }

    //解析文件
    public void setFile(File file) {
        this.file = file;
        this.begin = 134250496;
        queue_big.clear();
        InputStream input = null;
        try {
            if (file != null) {
                input = new FileInputStream(file.getPath());

                int packageSize = 2048;     //每包长度
                byte[] data = new byte[packageSize];
                int len = 0;//读取一个字节
                List<byte[]> dataList = new ArrayList<>();
                while ((len = input.read(data)) != -1) {
                    dataList.add(Arrays.copyOf(data, data.length));
                }
                createPackage(dataList);
            }
            handler.post(new Runnable() {
                @Override
                public void run() {
                    logAdapter.addLog(">>> 解析文件，组包完成，共" + queue_big.size() + "个2060包");
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
            CommToast.showToast(mContext, "文件解析失败");
        } finally {
            //关闭文件流，释放资源
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

//    //组包
//    private void createPackage(byte[] data, boolean isLast) {
//        //组包
//        byte[] bytes_0;    //固定值
//        byte[] bytes_1 = intToByte(begin);              //数据起始地址
//        byte[] bytes_2 = data;                          //文件数据
//        byte[] bytes_3;                                //累加和
//        byte[] bytes_4 = {(byte) 0x0D, (byte) 0x0A};   //结尾
//
//        if (isLast) {
//            bytes_0 = new byte[]{(byte) 0xF1, (byte) 0xF1};
//        } else {
//            bytes_0 = new byte[]{(byte) 0xF0, (byte) 0xF0};
//        }
//        int checkSum = 0;
//        for (int j = 0; j < bytes_2.length; j++) {
//            int item = ConvertUtils.hexString2Int(ConvertUtils.bytes2HexString(new byte[]{bytes_2[j]}));
//            checkSum += item;
//        }
//        bytes_3 = intToByte(checkSum);
//
////            if (i == 0) {
////                Log.i("checkSum:" + checkSum);
////                Log.i("bytes_3:" + ConvertUtils.bytes2HexString(bytes_3));
////            }
//
//        //组成最终包
//        ByteBuffer byteBuffer_final = ByteBuffer.allocate(bytes_0.length + bytes_1.length + bytes_2.length + bytes_3.length + bytes_4.length);
//        byteBuffer_final.put(bytes_0);
//        byteBuffer_final.put(bytes_1);
//        byteBuffer_final.put(bytes_2);
//        byteBuffer_final.put(bytes_3);
//        byteBuffer_final.put(bytes_4);
//        byte[] bytes_final = byteBuffer_final.array();
//
//        queue_big.add(bytes_final);
//        begin += 2048;
//    }

    //组包
    private void createPackage(List<byte[]> dataList) {
        for (int i = 0; i < dataList.size(); i++) {
            byte[] data = dataList.get(i);
            //组包
            byte[] bytes_0;    //固定值
            byte[] bytes_1 = intToByte(begin);              //数据起始地址
            byte[] bytes_2 = data;                          //文件数据
            byte[] bytes_3;                                //累加和
            byte[] bytes_4 = {(byte) 0x0D, (byte) 0x0A};   //结尾

            Log.i("data:"+ ConvertUtils.bytes2HexString(data));

            if (i == dataList.size() - 1) {
                bytes_0 = new byte[]{(byte) 0xF1, (byte) 0xF1};
            } else {
                bytes_0 = new byte[]{(byte) 0xF0, (byte) 0xF0};
            }
            int checkSum = 0;
            for (int j = 0; j < bytes_2.length; j++) {
                int item = ConvertUtils.hexString2Int(ConvertUtils.bytes2HexString(new byte[]{bytes_2[j]}));
                checkSum += item;
            }
            bytes_3 = intToByte(checkSum);

//            if (i == 0) {
//                Log.i("checkSum:" + checkSum);
//                Log.i("bytes_3:" + ConvertUtils.bytes2HexString(bytes_3));
//            }

            //组成最终包
            ByteBuffer byteBuffer_final = ByteBuffer.allocate(bytes_0.length + bytes_1.length + bytes_2.length + bytes_3.length + bytes_4.length);
            byteBuffer_final.put(bytes_0);
            byteBuffer_final.put(bytes_1);
            byteBuffer_final.put(bytes_2);
            byteBuffer_final.put(bytes_3);
            byteBuffer_final.put(bytes_4);
            byte[] bytes_final = byteBuffer_final.array();

            queue_big.add(bytes_final);
            begin += 2048;
        }
    }

    //发送大包
    public void sendBigBag() {
        if (queue_small.size() == 0) {
            //取一个大包，拆分成20小包
            if (queue_big.size() != 0) {
                byte[] bytes = queue_big.remove();
                for (int i = 0; i < 20; i++) {
                    byte[] bytes_small = new byte[103];
                    System.arraycopy(bytes, 103 * i, bytes_small, 0, 103);
                    queue_small.add(bytes_small);
                }
                logAdapter.addLog(">>> 开始发送2060字节大包");
            } else {
                //没有数据了，全部发完了
                Log.i("所有大包发送完毕");
                logAdapter.addLog("没有数据了");
                return;
            }
        }

        sendSmallBag();
    }

    //发送小包
    public void sendSmallBag() {
        if (!queue_small.isEmpty()) {
            byte[] bytes = queue_small.remove();
            sendData(bytes, DeviceDetailActivity.Tag_SendFile);
            logAdapter.addLog("发送" + bytes.length + "字节小包，剩余" + queue_small.size());
        } else {
            logAdapter.addLog(">>>2060字节发送完毕，等待主机回复。还剩" + queue_big.size() + "个包");
            EventBus.getDefault().post(new Event_SendBigBagSuccess());
            if (queue_big.size() == 0) {
                logAdapter.addLog("全部发送完成");
            }
        }
    }

    //发送文字
    public void sendData(byte[] data, String tag) {
        if (connection != null && connection.getConnectionState() != ConnectionState.SERVICE_DISCOVERED) {
            CommToast.showToast(mContext, "蓝牙未连接");
            return;
        }
        Log.d("发送数据");
        WriteCharacteristicBuilder builder = new RequestBuilderFactory().getWriteCharacteristicBuilder(serviceUUID, writeUUID, data);
        builder.setTag(tag);
        //根据需要设置写入配置
        int writeType = connection.hasProperty(serviceUUID, writeUUID, BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) ? BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE : BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT;
        builder.setWriteOptions(new WriteOptions.Builder().setPackageSize(data.length).setPackageWriteDelayMillis(5).setRequestWriteDelayMillis(10).setWaitWriteResult(true).setWriteType(writeType).build());
        //不设置回调，使用观察者模式接收结果
        builder.build().execute(connection);
    }


    private static byte[] intToByte(int i) {
        byte[] result = new byte[4];
        // 由高位到低位
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }


}
